package com.example.concurrentprogramming8016.reetrantlock;

import lombok.extern.slf4j.Slf4j;

import javax.swing.text.html.HTMLWriter;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author liyanhao
 * @Date 2023-01-05 23:23
 * 条件变量
 */
@Slf4j
public class ReentrantLockDemo7 {
    private static ReentrantLock lock = new ReentrantLock();
    private static Condition conditionSalt = lock.newCondition();
    private static Condition takeCon = lock.newCondition();
    private static boolean hasSalt = false;
    private static boolean hastakeout = false;

    //送盐
    public void sSalt() {
        lock.lock();
        try {
            while (!hasSalt) {
                log.debug("没有盐了.先等一会");
                try {
                    conditionSalt.await();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            //获得条件
            log.debug("有盐了，开始干活了");
        } finally {
            lock.unlock();
        }
    }

    public void sfood() {
        lock.lock();
        try {
            while (!hastakeout) {
                log.debug("没有盐歇一会，先去买盐吧");
                takeCon.await();
            }
            log.debug("饭做好了，开始干活吧");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ReentrantLockDemo7 reentrantLockDemo7 = new ReentrantLockDemo7();
        new Thread(() -> {
            reentrantLockDemo7.sfood();
        }).start();
        new Thread(() -> {
            reentrantLockDemo7.sSalt();
        }).start();
        new Thread(() -> {
            try {
                lock.lock();
                hasSalt = true;
                //唤醒送盐的线程
                conditionSalt.signal();
            } finally {
                lock.unlock();
            }
        }).start();
        new Thread(() -> {
            try {
                lock.lock();
                hastakeout = true;
                takeCon.signal();
            } finally {
                lock.unlock();
            }
        }).start();

    }
}
